package com.kevin.utilits.jmx;

import java.lang.management.MemoryUsage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;

import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class JmxUtils {
	private static Logger logger = Logger.getLogger(JmxUtils.class);
	private static MBeanServerConnection mbsc = null;
	private static String jmxURL = "service:jmx:rmi:///jndi/rmi://10.199.195.183:8060/jmxrmi";
	private static Map<String, String[]> map = new HashMap<String, String[]>();
	static {
		// 用户名、密码
		// map.put("jmx.remote.credentials", new String[] { "monitorRole", "QED" });
					
	}
	private static void getConnection() {
		try{
			JMXServiceURL serviceURL = new JMXServiceURL(jmxURL);
			JMXConnector connect = JMXConnectorFactory.connect(serviceURL);
			mbsc = connect.getMBeanServerConnection();
		}catch(Exception e){
			logger.error(e.getMessage(), e);
		}
	}

	public static void getObject() {
		try{
			Set<ObjectInstance> MBeanset = mbsc.queryMBeans(null, null);
			Iterator<ObjectInstance> MBeansetIterator = MBeanset.iterator();
			while (MBeansetIterator.hasNext()) {
				ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator.next();
				ObjectName objectName = objectInstance.getObjectName();
				MBeanInfo objectInfo = mbsc.getMBeanInfo(objectName);
				System.out.print("ObjectName:" + objectName.getCanonicalName() + ".");
				System.out.print("mehtodName:");
				for (int i = 0; i < objectInfo.getAttributes().length; i++) {
					System.out.print(objectInfo.getAttributes()[i].getName() + ",");
				}
				System.out.println();
			}
		}catch(Exception e){
			logger.error(e.getMessage(), e);
		}
	}

	public static void getHeap() {
		try{
			ObjectName heapObjName = new ObjectName("java.lang:type=Memory");
			// 堆内存
			MemoryUsage heapMemoryUsage = MemoryUsage.from((CompositeDataSupport) mbsc.getAttribute(heapObjName, "HeapMemoryUsage"));
			long commitMemory = heapMemoryUsage.getCommitted();// 堆当前分配
			long usedMemory = heapMemoryUsage.getUsed();
			System.out.print("堆内存总量:" + heapMemoryUsage.getMax() / 1024 + "KB,当前分配量:" + commitMemory / 1024 + "KB,当前使用率:"
					+ usedMemory / 1024 + "KB,");
			System.out.println("堆内存使用率:" + (int) usedMemory * 100 / commitMemory + "%");// 堆使用率
			// 栈内存
			MemoryUsage nonheapMemoryUsage = MemoryUsage.from((CompositeDataSupport) mbsc.getAttribute(heapObjName, "NonHeapMemoryUsage"));
			long noncommitMemory = nonheapMemoryUsage.getCommitted();
			long nonusedMemory = heapMemoryUsage.getUsed();
			System.out.println("栈内存使用率:" + (int) nonusedMemory * 100 / noncommitMemory + "%");
			// PermGen内存
			ObjectName permObjName = new ObjectName("java.lang:type=MemoryPool,name=Perm Gen");
			MemoryUsage permGenUsage = MemoryUsage.from((CompositeDataSupport) mbsc.getAttribute(permObjName, "Usage"));
			long committed = permGenUsage.getCommitted();// 持久堆大小
			long used = heapMemoryUsage.getUsed();//
			System.out.println("perm gen:" + (int) used * 100 / committed + "%");// 持久堆使用率
		}catch(Exception e){
			logger.error(e.getMessage(), e);
		}
	}

	public static void getYoungHeap() {
		try{
			ObjectName youngHeapObjName = new ObjectName("java.lang:type=MemoryPool,name=Eden Space");
			// 获取Mbean对象
			MBeanInfo youngHeapInfo = mbsc.getMBeanInfo(youngHeapObjName);
			// 获取对象的属性
			MBeanAttributeInfo[] youngHeapAttributes = youngHeapInfo.getAttributes();
			MemoryUsage youngHeapUsage = MemoryUsage.from((CompositeDataSupport) mbsc.getAttribute(youngHeapObjName, "Usage"));
			System.out.print("目前新生区分 配最大内存:" + youngHeapUsage.getMax() / 1024 + "KB,");
			System.out.print("新生区已分配:" + youngHeapUsage.getCommitted() / 1024 + "KB,");
			System.out.print("新生区初始化:" + youngHeapUsage.getInit() / 1024 + "KB,");
			System.out.println("新生区已使用" + youngHeapUsage.getUsed() / 1024 + "KB");
		}catch(Exception e){
			logger.error(e.getMessage(), e);
		}
	}

	public static void getAllThread() {
		try{
			ObjectName managerObjName = new ObjectName("Catalina:type=Manager,*");
			Set<ObjectName> s = mbsc.queryNames(managerObjName, null);
			for (ObjectName obj : s) {
	
				ObjectName objname = new ObjectName(obj.getCanonicalName());
				System.out.print("objectName:" + objname);
				System.out.print(",最大会话数:" + mbsc.getAttribute(objname, "maxActiveSessions") + ",");
				System.out.print("会话数:" + mbsc.getAttribute(objname, "activeSessions") + ",");
				System.out.println("活动会话数:" + mbsc.getAttribute(objname, "sessionCounter"));
			}
		}catch(Exception e){
			logger.error(e.getMessage(), e);
		}
	}
	
	public static void main(String[] args){
		getConnection();
		getAllThread();
		getHeap();
		getObject();
		getYoungHeap();
	}
}